package com.lyl.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.lyl.constant.Constants;
import com.lyl.domain.SysMenu;
import com.lyl.feign.JwtToken;
import com.lyl.feign.OAuth2FeignClient;
import com.lyl.model.LoginResult;
import com.lyl.service.SysLoginService;
import com.lyl.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author lylbell
 * @date 2021-06-22 14:51
 */
@Service
public class SysLoginServiceImpl implements SysLoginService {


    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;

    @Autowired
    private SysMenuService sysMenuService;

    //Y29pbi1hcGk6Y29pbi1zZWNyZXQ=为第三方客户端加密生成的
    @Value("${basic.token:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String basicToken ;


    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public LoginResult login(String username, String password) {

        ResponseEntity<JwtToken> tokenEntity = oAuth2FeignClient.getToken("password", username, password, "admin_type", basicToken);
        HttpStatus statusCode = tokenEntity.getStatusCode();
        if (statusCode != HttpStatus.OK) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        //获取远程调用授权服务器成功,jwtToken是我们自己添加的那个实体类信息。
        JwtToken jwtToken = tokenEntity.getBody();

        //获取token
        String token = jwtToken.getAccessToken();

        Jwt jwt = JwtHelper.decode(token);
        String jwtJsonStr = jwt.getClaims();
        JSONObject jwtJson = JSON.parseObject(jwtJsonStr);


        //获取菜单权限（通过id获取，解析token，获取其中的username,存的是id）
        String userName = jwtJson.getString("user_name");
        List<SysMenu> menus = sysMenuService.getMenusByUserId(Long.valueOf(userName));

        JSONArray authoritiesArray = jwtJson.getJSONArray("authorities");
        //组装权限
        List<SimpleGrantedAuthority> authorities = authoritiesArray.stream().map(authorityJson -> new SimpleGrantedAuthority(authorityJson.toString())).collect(Collectors.toList());

        //将token存储到redis里面
        redisTemplate.opsForValue().set(token,"",jwtToken.getExpiresIn(), TimeUnit.SECONDS);

        //现在的token没有bearer，在网关层过滤的时候，有将bearer去掉的操作，所以返回给前端的时候，需要加上bearer
        return new LoginResult(jwtToken.getTokenType() + " " + token,menus,authorities);
    }
}
